﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;

namespace Marmat.Forms
{
    public partial class BaseGrid
    {

        /// <summary>
        /// 通过行号获取行数据
        /// </summary>
        /// <param name="rowHandle"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public object GetRow(int rowHandle)
        {
            return this.BaseControl.MainView.GetRow(rowHandle);
        }

        /// <summary>
        /// 刷新数据源
        /// </summary>
        public void RefreshDataSource()
        {
            this.GridControl1.RefreshDataSource();
        }

        /// <summary>
        /// 将挂起的更改应用于基础数据源。
        /// </summary>
        public void EndEdit()
        {
            this.BindingSource.EndEdit();
        }

        /// <summary>
        /// 触发行变化事件
        /// </summary>
        /// <remarks></remarks>
        public void RaiseCurrentChanged()
        {
            CurrentChanged?.Invoke(this, new Views.Grid.GridEventArgs(this));
        }
        /// <summary>
        /// 返回指定坐标位置的单元格的显示内容。
        /// </summary>
        /// <param name="Row">行坐标，计算的时候包括分组行。</param>
        /// <param name="Column">列坐标</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public string GetRowCellDisplayText(int Row, Views.Grid.Column Column)
        {
            return Help.GetRowCellDisplayText(this.BaseControl.MainView, Row, Column);
        }

        /// <summary>
        /// 获得或设置指定坐标位置的单元格的值。
        /// </summary>
        /// <param name="Row">行坐标，计算的时候包括分组行。</param>
        /// <param name="Column">列坐标</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public object GetRowCellValue(int Row, Views.Grid.Column Column)
        {
            return Help.GetRowCellValue(this.BaseControl.MainView, Row, Column);
        }

        /// <summary>
        /// 获取选择的行集合的行号
        /// </summary>
        /// <returns></returns>
        public int[] GetSelectedRows()
        {
            return this.gridView1.GetSelectedRows();
        }

        /// <summary>
        /// 从当前选择中删除一行
        /// </summary>
        public void UnselectRow(int rowHandle)
        {
            this.gridView1.UnselectRow(rowHandle);
        }

        /// <summary>
        /// 删除行
        /// </summary>
        /// <param name="rowHandle">一个整数值，它是要删除的行的句柄。</param>
        public void DeleteRow(int rowHandle)
        {
            if (this.GridControl1.MainView is DevExpress.XtraGrid.Views.Grid.GridView)
            {
                ((DevExpress.XtraGrid.Views.Grid.GridView)this.GridControl1.MainView).DeleteRow(rowHandle);
            }
        }

        /// <summary>
        /// 删除行
        /// </summary>
        public void DeleteRow(object value)
        {
            if (this.DataSource is IList)
            {
                ((IList)this.DataSource).Remove(value);
            }
            else if (this.DataSource is DataTable)
            {
                ((DataTable)this.DataSource).Rows.Remove((DataRow)value);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
        /// <summary>
        /// 按单元格的值定位记录
        /// </summary>
        /// <param name="fieldName">字段名称</param>
        /// <param name="val">单元格的值</param>
        public int LocateByValue(string fieldName, object val)
        {
            if (this.GridControl1.MainView is DevExpress.XtraGrid.Views.Grid.GridView)
            {
                return ((DevExpress.XtraGrid.Views.Grid.GridView)this.GridControl1.MainView).LocateByValue(fieldName, val);
            }
            else
            {
                return -1;
            }
        }

        /// <summary>
        /// 通过行的对象查找行所在的行号。
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public int FindRow(object row)
        {
            return this.GetMainView().FindRow(row);
        }

        /// <summary>
        /// 通过表达式查找行所在的行号。
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public int FindRow(Func<object, bool> expression)
        {
            for (int rowHandle = 0, loopTo = this.RowCount - 1; rowHandle <= loopTo; rowHandle++)
            {
                var row = this.GetRow(rowHandle);
                if (expression(row))
                {
                    return rowHandle;
                }
            }

            return -1;
        }

        /// <summary>
        /// 按单元格的显示值定位记录
        /// </summary>
        /// <param name="fieldName">字段名称</param>
        /// <param name="val">单元格的显示值</param>
        public int LocateByDisplayText(string fieldName, object val)
        {
            return this.LocateByDisplayText(0, fieldName, val);
        }

        /// <summary>
        /// 按单元格的显示值定位记录
        /// </summary>
        /// <param name="startRowHandle">开始查找的行</param>
        /// <param name="fieldName">字段名称</param>
        /// <param name="val">单元格的显示值</param>
        public int LocateByDisplayText(int startRowHandle, string fieldName, object val)
        {
            if (this.GridControl1.MainView is DevExpress.XtraGrid.Views.Grid.GridView)
            {
                return ((DevExpress.XtraGrid.Views.Grid.GridView)this.GridControl1.MainView).LocateByDisplayText(0, this.Columns[fieldName].GridColumn, Convert.ToString(val));
            }
            else
            {
                return -1;
            }
        }

        protected internal void SetValue(string PropertyName, object Value)
        {
            switch (PropertyName)
            {
                case "OptionsCustomization.AllowClickSort":
                    {
                        this.BaseGridView.OptionsCustomization.AllowSort = Convert.ToBoolean(Value);
                        this.BaseBandedGridView.OptionsCustomization.AllowSort = Convert.ToBoolean(Value);
                        this.BaseAdvBandedGridView.OptionsCustomization.AllowSort = Convert.ToBoolean(Value);
                        break;
                    }

                case "AllowColumnMoving":
                    {
                        this.BaseGridView.OptionsCustomization.AllowColumnMoving = Convert.ToBoolean(Value);
                        this.BaseBandedGridView.OptionsCustomization.AllowColumnMoving = Convert.ToBoolean(Value);
                        this.BaseAdvBandedGridView.OptionsCustomization.AllowColumnMoving = Convert.ToBoolean(Value);
                        break;
                    }

                case "AllowColumnResizing":
                    {
                        this.BaseGridView.OptionsCustomization.AllowColumnResizing = Convert.ToBoolean(Value);
                        this.BaseBandedGridView.OptionsCustomization.AllowColumnResizing = Convert.ToBoolean(Value);
                        this.BaseAdvBandedGridView.OptionsCustomization.AllowColumnResizing = Convert.ToBoolean(Value);
                        break;
                    }

                case "NewItemRowPosition":
                    {
                        this.BaseGridView.OptionsView.NewItemRowPosition = (DevExpress.XtraGrid.Views.Grid.NewItemRowPosition)Value;
                        this.BaseBandedGridView.OptionsView.NewItemRowPosition = (DevExpress.XtraGrid.Views.Grid.NewItemRowPosition)Value;
                        this.BaseAdvBandedGridView.OptionsView.NewItemRowPosition = (DevExpress.XtraGrid.Views.Grid.NewItemRowPosition)Value;
                        break;
                    }

                case "OptionsView.ShowGroupPanel":
                    {
                        this.BaseGridView.OptionsView.ShowGroupPanel = Convert.ToBoolean(Value);
                        this.BaseBandedGridView.OptionsView.ShowGroupPanel = Convert.ToBoolean(Value);
                        this.BaseAdvBandedGridView.OptionsView.ShowGroupPanel = Convert.ToBoolean(Value);
                        break;
                    }

                case "OptionsView.ColumnAutoWidth":
                    {
                        this.BaseGridView.OptionsView.ColumnAutoWidth = Convert.ToBoolean(Value);
                        this.BaseBandedGridView.OptionsView.ColumnAutoWidth = Convert.ToBoolean(Value);
                        this.BaseAdvBandedGridView.OptionsView.ColumnAutoWidth = Convert.ToBoolean(Value);
                        break;
                    }

                case "OptionsBehavior.CopyToClipboardWithColumnHeaders":
                    {
                        this.BaseGridView.OptionsClipboard.CopyColumnHeaders = (DevExpress.Utils.DefaultBoolean)Value;
                        this.BaseBandedGridView.OptionsClipboard.CopyColumnHeaders = (DevExpress.Utils.DefaultBoolean)Value;
                        this.BaseAdvBandedGridView.OptionsClipboard.CopyColumnHeaders = (DevExpress.Utils.DefaultBoolean)Value;
                        // Me.BaseGridView.OptionsBehavior.CopyToClipboardWithColumnHeaders = Value
                        // Me.BaseBandedGridView.OptionsBehavior.CopyToClipboardWithColumnHeaders = Value
                        // Me.BaseAdvBandedGridView.OptionsBehavior.CopyToClipboardWithColumnHeaders = Value
                        break;
                    }
                case "OptionsMenu.EnableGroupPanelMenu":
                    {
                        this.BaseGridView.OptionsMenu.EnableGroupPanelMenu = Convert.ToBoolean(Value);
                        this.BaseBandedGridView.OptionsMenu.EnableGroupPanelMenu = Convert.ToBoolean(Value);
                        this.BaseAdvBandedGridView.OptionsMenu.EnableGroupPanelMenu = Convert.ToBoolean(Value);
                        break;
                    }
            }
        }

        /* TODO ERROR: Skipped RegionDirectiveTrivia */
        /// <summary>
        /// 重新生成表头。
        /// </summary>
        /// <param name="sep">分割符</param>
        /// <remarks></remarks>
        public void BuildHeader(string sep)
        {
            var Items = new List<MultiRowHeaderInfo>();
            foreach (Views.DataGrid.Column dc in this.Columns)
            {
                if (dc.Visible)
                {
                    string Caption = dc.Caption;
                    if (Caption is null)
                        Caption = "";
                    MultiRowHeaderInfo item = null;
                    var list = Items;
                    var vals = Caption.Split(sep.ToCharArray());
                    foreach (string str in vals)
                    {
                        item = this.BuildHeader_GetLastColumn(list, str);
                        list = item.Items;
                    }

                    item.Column = dc;
                }
            }

            this.Headers.Clear();
            foreach (MultiRowHeaderInfo item in Items)
                this.BuildHeader_CreateHeader(item, this.Headers);
        }

        /// <summary>
        /// 获取集合相同名称的最后一列，如果不存在相同名称的最后一列，则创建一列
        /// </summary>
        /// <param name="Items"></param>
        /// <param name="Name"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        protected internal MultiRowHeaderInfo BuildHeader_GetLastColumn(List<MultiRowHeaderInfo> Items, string Name)
        {
            MultiRowHeaderInfo Item = null;
            if (Items.Count > 0 && (Items[Items.Count - 1].Name ?? "") == (Name ?? ""))
            {
                Item = Items[Items.Count - 1];
            }
            else
            {
                Item = new MultiRowHeaderInfo();
                Item.Name = Name;
                Items.Add(Item);
            }

            return Item;
        }

        /// <summary>
        /// 创建多层表头
        /// </summary>
        /// <param name="info"></param>
        /// <param name="collection"></param>
        /// <remarks></remarks>
        protected internal void BuildHeader_CreateHeader(MultiRowHeaderInfo info, Views.Grid.BandCollection collection)
        {
            var band = new Views.Grid.Band();
            collection.Add(band);
            band.Name = info.Name;
            if (info.Column is object)
            {
                band.Columns.Add(info.Column);
            }

            foreach (MultiRowHeaderInfo item in info.Items)
                this.BuildHeader_CreateHeader(item, band.Bands);
        }
    }
}